<template>
  <div class="domRect-test-event">
    <h1>{{ message }}</h1>
    <h2>一、基础知识铺垫：</h2>
    <p>首先我们先了解一下getBoundingClientRect 、 getClientRects 这两个是什么</p>
    <section>
        <h3>1、getBoundingClientRect</h3>
        <p>用于获得页面中某个元素的左，上，右和下分别相对浏览器视窗的位置</p>
        <img src="../../images/somethingInterssting/getBoundingClientRect.png" class="getBoundingClientRectClass"/>
        <div class="info">
            <div class="left" id="domrect1">
                <p>
                    右侧查看我距离窗口左上角的位置
                </p>
                <img src="../../images/somethingInterssting/console.jpg" style="width:270px" class="getBoundingClientRectClass" />
            </div>
            <div class="right">
                <p>getBoundingClientRect的返回值（可放大缩小窗口尝试）</p>
                <p>top：{{positionParams.top}}</p>
                <p>left：{{positionParams.left}}</p>
                <p>bottom：{{positionParams.bottom}}</p>
                <p>right：{{positionParams.right}}</p>
                <p>width：{{positionParams.width}} （注意：ie没有此值，需要自己计算）</p>
                <p>height：{{positionParams.height}} （注意：ie没有此值，需要自己计算）</p>
            </div>
        </div>
        <code v-pre>
                <pre>
    &lt;div class="left" id="domrect1"&gt;
        &lt;span&gt;
            右侧查看我距离窗口左上角的位置
        &lt;/span&gt;
    &lt;/div&gt;
    &lt;div class="right"&gt;
        &lt;p&gt;getBoundingClientRect的返回值（可放大缩小窗口尝试）&lt;/p&gt;
        &lt;p&gt;top：{{positionParams.top}}&lt;/p&gt;
        &lt;p&gt;left：{{positionParams.left}}&lt;/p&gt;
        &lt;p&gt;bottom：{{positionParams.bottom}}&lt;/p&gt;
        &lt;p&gt;right：{{positionParams.right}}&lt;/p&gt;
        &lt;p&gt;width：{{positionParams.width}} （注意：ie没有此值，需要自己计算）&lt;/p&gt;
        &lt;p&gt;height：{{positionParams.height}} （注意：ie没有此值，需要自己计算）&lt;/p&gt;
    &lt;/div&gt;

position (): void {
    this.positionParams = (document.getElementById('domrect1') as HTMLElement).getBoundingClientRect() as DOMRect;
}
                </pre>
            </code>
    </section>
    <section>
        <h3>2、getClientRects</h3>
        <p style="text-indent: 2em;">getClientRects()返回一个TextRectangle集合，页面显示多少行文本，就返回多少个TextRectangle，
        它只对span、a、i这种行内元素或者 display：inline 的元素有效，否则都只会返回一个元素。并且父级设置flex 等属性也会影响他只返回一个元素。</p>
        <div class="info">
            <div class="left left2">
                <div>
                    <span id="domrect2">
                        右侧查看我距离窗口左上角的位置右侧查看我距离窗口
                        左上角的位置右侧查看我距离窗口左上
                        角的位置右侧查看我距离窗口左上角的位置右侧查看我距离窗
                        口左上角的位置右侧查看我距离窗口左上角的位置右侧查看我距
                        离窗口左上角的位置离窗口左上角的位置离窗口左上角的位置
                        离窗口左上角的位置离窗口左上角的位置
                    </span>
                </div>
            </div>
            <div class="right">
                <img src="../../images/somethingInterssting/console2.jpg" style="width:100%" class="getBoundingClientRectClass"  />
            </div>
        </div>
        <code>
            <pre>
                &lt;span id="domrect2"&gt;
                    右侧查看我距离窗口左上角的位置右侧查看我距离窗口
                    左上角的位置右侧查看我距离窗口左上
                    角的位置右侧查看我距离窗口左上角的位置右侧查看我距离窗
                    口左上角的位置右侧查看我距离窗口左上角的位置右侧查看我距
                    离窗口左上角的位置离窗口左上角的位置离窗口左上角的位置
                    离窗口左上角的位置离窗口左上角的位置
                &lt;/span&gt;

            console.error((document.getElementById('domrect2') as HTMLElement).getClientRects() as DOMRectList);
            </pre>
        </code>
    </section>
    <h2>二、懒加载基本实现</h2>
    <p style="text-indent: 2em;">既然知道了getBoundingClientRect可以获取相对窗口的位置，那我们可以利用它来实现我们的懒加载，下面是50张图片，我们要实现只有图片出现在窗口内再开始加载。</p>
    <p>我们先看代码吧：</p>
    <code>
        <pre>
            &lt;img data-src="../../images/somethingInterssting/console2.jpg" style="width:100%" 
                class="getBoundingClientRectClass lazyLoad" v-for="item in 50" :key="item"/&gt;

    clientHeight: number = document.documentElement.clientHeight
    // 手机屏获取到的不是实际像素高度
    radio: number = window.devicePixelRatio || 1
    presentLength: number = 0
    imgLikeArray: HTMLCollectionOf&lt;Element&gt; = document.getElementsByClassName('lazyLoad')
    lazyLoad () {
        let len: number = this.imgLikeArray.length;

        for (let i = 0; i &lt; len; i++){
            let top: number = this.imgLikeArray[i].getBoundingClientRect().top;

            // 保证只有在视口内的图片且没有被加载过的图片被重新赋值
            if (top &lt; this.clientHeight * this.radio && top &gt; -300 && !(this.imgLikeArray[i] as HTMLImageElement).src) {
                (this.imgLikeArray[i] as HTMLImageElement).src = 
                ((this.imgLikeArray[i] as HTMLImageElement).getAttribute('data-src') as string) + `?_=${Date.now()}`;
            }
        }
    }
        </pre>
    </code>
    <p>下面是事例：快速滚动可明显看出图片浅蓝色背景，如果停留在页面底部进行刷新，快速上滑也可以看到浅蓝色背景（请刷新页面重复体验）</p>
    <section>
        <img data-src="images/console2.a8d35.jpg" style="width:100%" class="getBoundingClientRectClass lazyLoad" v-for="item in 50" :key="item"/>
    </section>
    <p class="page-end">The End</p>
  </div>
</template>

<script lang="ts">
    import Vue from 'vue';
    import Component from 'vue-class-component';

    @Component({
        // 所有的组件选项都可以放在这里
    })
    export default class domRect extends Vue {
        // data 在这
        message: string = '利用DOMRect 简单实现整个页面的懒加载'

        positionParams: any = {}
        position (): void {
            this.positionParams = (document.getElementById('domrect1') as HTMLElement).getBoundingClientRect() as DOMRect;
        }

        positionParams2: any = []
        position2 (): void {
            console.error((document.getElementById('domrect2') as HTMLElement).getClientRects() as DOMRectList);
        }

        clientHeight: number = document.documentElement.clientHeight
        radio: number = window.devicePixelRatio || 1
        presentLength: number = 0
        imgLikeArray: HTMLCollectionOf<Element> = document.getElementsByClassName('lazyLoad')
        lazyLoad () {
            let len: number = this.imgLikeArray.length;

            for (let i = 0; i < len; i++){
                let top: number = this.imgLikeArray[i].getBoundingClientRect().top;

                // 保证只有在视口内的图片且没有被加载过的图片被重新赋值
                if (top < this.clientHeight * this.radio && top > -300 && !(this.imgLikeArray[i] as HTMLImageElement).src) {
                    (this.imgLikeArray[i] as HTMLImageElement).src = ((this.imgLikeArray[i] as HTMLImageElement).getAttribute('data-src') as string) + `?_=${Date.now()}`;
                }
            }
        }

        mounted() {
            this.position();
            this.position2();
            this.lazyLoad();
            window.addEventListener('scroll', this.position);
            window.addEventListener('scroll', this.position2);
            window.addEventListener('scroll', this.lazyLoad);
        }

        beforeDestroy () {
            window.removeEventListener('scroll', this.position);
            window.removeEventListener('scroll', this.position2);
            window.removeEventListener('scroll', this.lazyLoad);
        }
    }
</script>
<style lang="scss">
.domRect-test-event{
    width: 100%;
    .getBoundingClientRectClass{
        width: 100%;
        box-shadow: 5px 5px 5px #888888;
        margin-bottom: 20px;
    }
    section{
        .info{
            display: flex;
            min-height: 30vw;
            margin-bottom: 20px;
            flex-wrap: wrap;
            >div{
                align-items: flex-start;
                flex-wrap: nowrap;
                width: 30vw;
                min-width: 300px;
                max-width: 330px;
                // height: 30vw;
                // min-height: 300px;
                flex-grow: 1;
                word-spacing: 10px;
                display: flex;
                justify-content:center;
                box-sizing: border-box;
                padding: 30px;
            }
            .left{
                flex-grow: 0;
                flex-shrink: 0;
                background: #f4f4f4;
                flex-direction: column;
                text-align: center;
                align-items:center;
                font-size: 30px;
                line-height: 1.5em;
            }
            .left2{
                font-size: 16px;
            }
            .right{
                flex-direction: column;
                p{
                    margin: 5px;
                }
            }
        }
        .lazyLoad{
            height: 30vw;
            max-height: 300px;
            width: 100%;
            background: lightblue;
        }
    }
}
</style>